home *** CD-ROM | disk | FTP | other *** search
- {$C+}
- PROGRAM game(INPUT,OUTPUT);
- VAR
- i_move_first : BOOLEAN;
- counter_0,
- counter_1,
- counter_2,
- counter_3,
- counter_4,
- counter_5,
- counter_6,
- counter_7,
- level_of_difficulty,
- max_plys,
- my_score,
- plys_left,
- tiles_visited,
- your_moves_left,
- your_score : INTEGER;
- board : ARRAY [0..9,0..4,0..4] OF INTEGER;
- my_column,
- my_row,
- your_column,
- your_row : ARRAY [0..9] OF INTEGER;
- column_change,
- row_change : ARRAY [1..8] OF INTEGER;
- PROCEDURE display_rules;
- BEGIN
- WRITELN(OUTPUT,
- ' Square tiles cover a board five tiles high and five tiles');
- WRITELN(OUTPUT,
- 'wide. You start on the lower left tile and I start on the upper');
- WRITELN(OUTPUT,
- 'right tile. We take turns moving like a knight in a chess game.');
- WRITELN(OUTPUT,
- 'Neither of us may move off the board. Each tile that has not yet');
- WRITELN(OUTPUT,
- 'been occupied has a number of dollars on it. As one moves onto a');
- WRITELN(OUTPUT,
- 'tile, one collects the dollars on that tile. We each get fifteen');
- WRITELN(OUTPUT,
- 'moves. Whoever collects more dollars wins.');
- END;
- FUNCTION you_move_first : BOOLEAN;
- VAR
- response_okay : BOOLEAN;
- response : CHAR;
- BEGIN
- WRITELN(OUTPUT,' ');
- REPEAT
- WRITE(OUTPUT,' Do you want to move first or second? ');
- READLN(INPUT,response);
- IF ((response = 'f') OR (response = 'F')) THEN
- BEGIN
- response_okay:=TRUE;
- you_move_first:=TRUE
- END
- ELSE
- IF ((response = 's') OR (response = 'S')) THEN
- BEGIN
- response_okay:=TRUE;
- you_move_first:=FALSE
- END
- ELSE
- response_okay:=FALSE
- UNTIL
- (response_okay)
- END;
- PROCEDURE get_level_of_difficulty;
- BEGIN
- WRITELN(OUTPUT,' ');
- REPEAT
- WRITE(' Level of difficulty (1-9)? ');
- READLN(INPUT,level_of_difficulty)
- UNTIL
- ((level_of_difficulty >= 1) AND (level_of_difficulty <= 9))
- END;
- PROCEDURE get_game_number;
- VAR
- char_index : INTEGER;
- game_number_okay : BOOLEAN;
- game_number : STRING[8];
- BEGIN
- WRITELN(OUTPUT,' ');
- game_number_okay:=FALSE;
- REPEAT
- WRITE(' Eight digit game number? ');
- READLN(INPUT,game_number);
- WHILE (LENGTH(game_number) < 8) DO
- game_number:=CONCAT('0',game_number);
- game_number_okay:=TRUE;
- char_index:=1;
- WHILE ((char_index <= 8) AND (game_number_okay)) DO
- IF ((game_number[char_index] < '0')
- OR (game_number[char_index] > '9')) THEN
- game_number_okay:=FALSE
- ELSE
- char_index:=char_index+1
- UNTIL
- (game_number_okay);
- counter_0:=ORD(game_number[8])-ORD('0');
- counter_1:=ORD(game_number[7])-ORD('0');
- counter_2:=ORD(game_number[6])-ORD('0');
- counter_3:=ORD(game_number[5])-ORD('0');
- counter_4:=ORD(game_number[4])-ORD('0');
- counter_5:=ORD(game_number[3])-ORD('0');
- counter_6:=ORD(game_number[2])-ORD('0');
- counter_7:=ORD(game_number[1])-ORD('0')
- END;
- FUNCTION uniform : REAL;
- TYPE
- substitution_array = ARRAY [0..99] OF INTEGER;
- CONST
- substitution_high : substitution_array =
- (4,1,2,8,8,9,9,6,5,7,2,1,2,9,8,8,6,3,5,1,9,5,4,4,9,8,6,0,8,0,
- 6,0,2,4,1,9,2,0,7,4,7,3,0,0,2,6,8,9,4,0,8,3,2,3,2,5,2,4,6,9,
- 7,9,1,3,5,7,1,1,4,5,8,1,6,0,5,7,8,2,3,3,7,3,5,1,7,5,4,0,3,6,
- 3,7,7,1,9,4,0,5,6,6);
- substitution_low : substitution_array =
- (1,2,2,1,5,5,4,6,4,6,4,4,5,6,6,3,0,9,6,5,7,2,0,9,3,4,2,3,9,1,
- 9,9,9,3,8,9,3,4,1,5,0,5,2,7,0,8,8,0,4,5,0,3,6,8,1,7,8,8,7,1,
- 3,2,7,7,1,8,0,3,7,5,2,6,4,0,9,9,7,7,4,6,2,0,0,1,7,3,6,6,1,1,
- 2,4,5,9,8,2,8,8,3,5);
- VAR
- iteration,
- seed_0,
- seed_1,
- seed_2,
- seed_3,
- seed_4,
- seed_5,
- seed_6,
- seed_7,
- substitution_index,
- tem_0,
- tem_1,
- tem_3,
- tem_int
- : INTEGER;
- dividend,
- sum : REAL;
- BEGIN
- tem_int:=counter_0+1;
- IF tem_int <= 9 THEN
- counter_0:=tem_int
- ELSE
- BEGIN
- counter_0:=0;
- tem_int:=counter_1+1;
- IF tem_int <= 9 THEN
- counter_1:=tem_int
- ELSE
- BEGIN
- counter_1:=0;
- tem_int:=counter_2+1;
- IF tem_int <= 9 THEN
- counter_2:=tem_int
- ELSE
- BEGIN
- counter_2:=0;
- tem_int:=counter_3+1;
- IF tem_int <= 9 THEN
- counter_3:=tem_int
- ELSE
- BEGIN
- counter_3:=0;
- tem_int:=counter_4+1;
- IF tem_int <= 9 THEN
- counter_4:=tem_int
- ELSE
- BEGIN
- counter_4:=0;
- tem_int:=counter_5+1;
- IF tem_int <= 9 THEN
- counter_5:=tem_int
- ELSE
- BEGIN
- counter_5:=0;
- tem_int:=counter_6+1;
- IF tem_int <= 9 THEN
- counter_6:=tem_int
- ELSE
- BEGIN
- counter_6:=0;
- tem_int:=counter_7+1;
- IF tem_int <= 9 THEN
- counter_7:=tem_int
- ELSE
- counter_7:=0
- END
- END
- END
- END
- END
- END
- END;
- seed_0:=counter_0;
- seed_1:=counter_1;
- seed_2:=counter_2;
- seed_3:=counter_3;
- seed_4:=counter_4;
- seed_5:=counter_5;
- seed_6:=counter_6;
- seed_7:=counter_7;
- FOR iteration:=1 TO 8 DO
- BEGIN
- substitution_index:=10*seed_1+seed_0;
- tem_0:=substitution_low[substitution_index];
- tem_1:=substitution_high[substitution_index];
- substitution_index:=10*seed_3+seed_2;
- seed_0:=substitution_low[substitution_index];
- tem_3:=substitution_high[substitution_index];
- substitution_index:=10*seed_5+seed_4;
- seed_2:=substitution_low[substitution_index];
- seed_1:=substitution_high[substitution_index];
- substitution_index:=10*seed_7+seed_6;
- seed_5:=substitution_low[substitution_index];
- seed_7:=substitution_high[substitution_index];
- seed_3:=tem_0;
- seed_6:=tem_1;
- seed_4:=tem_3
- END;
- tem_int:=1000*seed_3+100*seed_2+10*seed_1+seed_0;
- sum:=tem_int;
- sum:=sum/10000.0;
- tem_int:=1000*seed_7+100*seed_6+10*seed_5+seed_4;
- dividend:=tem_int;
- sum:=(dividend+sum)/10000.0;
- uniform:=sum
- END;
- PROCEDURE set_up_board;
- VAR
- column,
- row : INTEGER;
- BEGIN
- FOR row:=0 TO 4 DO
- FOR column:=0 TO 4 DO
- board[0,column,row]:=1+TRUNC(9*uniform);
- board[0,0,0]:=0;
- board[0,4,4]:=0
- END;
- PROCEDURE display_board;
- VAR
- column,
- row : INTEGER;
- BEGIN
- WRITELN(OUTPUT,' ');
- FOR row:=4 DOWNTO 0 DO
- BEGIN
- WRITE(OUTPUT,' ');
- FOR column:=0 TO 4 DO
- IF ((column = my_column[0]) AND (row = my_row[0])) THEN
- WRITE(OUTPUT,' +')
- ELSE
- IF ((column = your_column[0]) AND (row = your_row[0])) THEN
- WRITE(OUTPUT,' *')
- ELSE
- WRITE(OUTPUT,board[0,column,row]:2);
- WRITELN(OUTPUT,' ')
- END;
- WRITELN(OUTPUT,' ');
- WRITE(OUTPUT,' My winnings: ');
- WRITE(OUTPUT,my_score:3);
- WRITE(OUTPUT,' Your winnings: ');
- WRITELN(OUTPUT,your_score:3)
- END;
- FUNCTION on_board(VAR column,row : INTEGER) : BOOLEAN;
- BEGIN
- IF column < 0 THEN
- on_board:=FALSE
- ELSE
- IF column > 4 THEN
- on_board:=FALSE
- ELSE
- IF row < 0 THEN
- on_board:=FALSE
- ELSE
- IF row > 4 THEN
- on_board:=FALSE
- ELSE
- on_board:=TRUE
- END;
- PROCEDURE get_your_move;
- VAR
- change_index,
- board_column,
- board_row,
- increment,
- limit,
- move_column,
- move_row,
- next_column,
- next_row,
- permissible_move_count,
- permissible_move_index,
- tem_1 : INTEGER;
- permissible_move : ARRAY [1..8] OF INTEGER;
- move : ARRAY [1..8,-2..2,-2..2] OF INTEGER;
- BEGIN
- WRITELN(OUTPUT,' ');
- WRITE(OUTPUT,' You have ');
- WRITE(OUTPUT,your_moves_left:2);
- WRITELN(OUTPUT,' moves left.');
- WRITELN(OUTPUT,' ');
- WRITELN(OUTPUT,' Permissible moves:');
- permissible_move_count:=0;
- FOR change_index:=1 TO 8 DO
- BEGIN
- next_column:=your_column[0]+column_change[change_index];
- next_row:=your_row[0]+row_change[change_index];
- IF on_board(next_column,next_row) THEN
- BEGIN
- permissible_move_count:=permissible_move_count+1;
- permissible_move[permissible_move_count]:=change_index;
- FOR move_column:=-2 TO 2 DO
- FOR move_row:=-2 TO 2 DO
- move[permissible_move_count,move_column,move_row]:=-2;
- move[permissible_move_count,0,0]:=-1;
- limit:=column_change[change_index];
- IF limit > 0 THEN
- increment:=1
- ELSE
- increment:=-1;
- move_column:=0;
- move_row:=0;
- board_column:=your_column[0];
- board_row:=your_row[0];
- REPEAT
- move_column:=move_column+increment;
- board_column:=board_column+increment;
- move[permissible_move_count,move_column,move_row]
- :=board[0,board_column,board_row]
- UNTIL
- (move_column = limit);
- limit:=row_change[change_index];
- IF limit > 0 THEN
- increment:=1
- ELSE
- increment:=-1;
- REPEAT
- move_row:=move_row+increment;
- board_row:=board_row+increment;
- move[permissible_move_count,move_column,move_row]
- :=board[0,board_column,board_row]
- UNTIL
- (move_row = limit)
- END
- END;
- WRITELN(OUTPUT,' ');
- FOR move_row:=2 DOWNTO -2 DO
- BEGIN
- WRITE(OUTPUT,' ');
- FOR permissible_move_index:=1 TO permissible_move_count DO
- BEGIN
- WRITE(OUTPUT,' ');
- FOR move_column:=-2 TO 2 DO
- BEGIN
- tem_1:=move[permissible_move_index,move_column,move_row];
- IF tem_1 < -1 THEN
- WRITE(OUTPUT,' ')
- ELSE
- IF tem_1 < 0 THEN
- WRITE(OUTPUT,'*')
- ELSE
- WRITE(OUTPUT,tem_1:1)
- END
- END;
- WRITELN(OUTPUT,' ')
- END;
- WRITE(OUTPUT,' ');
- FOR permissible_move_index:=1 TO permissible_move_count DO
- BEGIN
- WRITE(OUTPUT,' Move ');
- WRITE(OUTPUT,permissible_move_index:1)
- END;
- WRITELN(OUTPUT,' ');
- WRITELN(OUTPUT,' ');
- REPEAT
- WRITE(OUTPUT,' Which move do you wish to make? ');
- READLN(INPUT,permissible_move_index)
- UNTIL
- ((permissible_move_index >= 1)
- AND (permissible_move_index <= permissible_move_count));
- change_index:=permissible_move[permissible_move_index];
- next_column:=your_column[0]+column_change[change_index];
- next_row:=your_row[0]+row_change[change_index];
- your_column[0]:=next_column;
- your_row[0]:=next_row;
- your_score:=your_score+board[0,next_column,next_row];
- IF board[0,next_column,next_row] > 0 THEN
- tiles_visited:=tiles_visited+1;
- board[0,next_column,next_row]:=0;
- your_moves_left:=your_moves_left-1;
- plys_left:=plys_left-1
- END;
- PROCEDURE make_my_move;
- VAR
- finished,
- skip_branch,
- valid_move_found : BOOLEAN;
- change_index,
- change_limit,
- column,
- final_change_index,
- max_depth,
- next_column,
- next_row,
- ply,
- ply_minus_1,
- ply_plus_1,
- row,
- tem_1,
- tem_2 : INTEGER;
- branch : ARRAY [1..9] OF INTEGER;
- min_max : ARRAY [1..9,1..8] OF INTEGER;
- partial_sum : ARRAY [0..9] OF INTEGER;
- BEGIN
- max_depth:=max_plys;
- IF plys_left < max_depth THEN
- max_depth:=plys_left;
- partial_sum[0]:=my_score-your_score;
- FOR ply:=1 TO max_depth DO
- BEGIN
- IF ODD(ply) THEN
- FOR change_index:=1 TO 8 DO
- min_max[ply,change_index]:=32000
- ELSE
- FOR change_index:=1 TO 8 DO
- min_max[ply,change_index]:=-32000;
- branch[ply]:=8;
- END;
- branch[1]:=0;
- ply:=max_depth;
- REPEAT
- finished:=FALSE;
- WHILE ((ply >= 1) AND (NOT finished)) DO
- BEGIN
- branch[ply]:=branch[ply]+1;
- IF branch[ply] > 8 THEN
- BEGIN
- branch[ply]:=1;
- ply_plus_1:=ply;
- ply:=ply-1;
- ply_minus_1:=ply-1;
- IF ply > 0 THEN
- BEGIN
- IF ODD(ply) THEN
- BEGIN
- tem_2:=min_max[ply,branch[ply]];
- FOR change_index:=1 TO 8 DO
- BEGIN
- tem_1:=min_max[ply_plus_1,change_index];
- IF tem_1 > -32000 THEN
- BEGIN
- IF tem_1 < tem_2 THEN tem_2:=tem_1;
- min_max[ply_plus_1,change_index]:=-32000
- END
- END;
- min_max[ply,branch[ply]]:=tem_2;
- IF tem_2 < 32000 THEN
- BEGIN
- IF ply_minus_1 > 0 THEN
- BEGIN
- change_index:=1;
- change_limit:=branch[ply_minus_1];
- skip_branch:=FALSE;
- WHILE ((change_index < change_limit)
- AND (NOT skip_branch)) DO
- BEGIN
- tem_1:=min_max[ply_minus_1,change_index];
- IF tem_1 > -32000 THEN
- IF tem_2 >= tem_1 THEN
- skip_branch:=TRUE
- ELSE
- change_index:=change_index+1
- ELSE
- change_index:=change_index+1
- END;
- IF skip_branch THEN
- BEGIN
- change_limit:=branch[ply];
- FOR change_index:=1 TO change_limit DO
- min_max[ply,change_index]:=32000;
- branch[ply]:=1;
- ply:=ply_minus_1
- END
- END
- END
- END
- ELSE
- BEGIN
- tem_2:=min_max[ply,branch[ply]];
- FOR change_index:=1 TO 8 DO
- BEGIN
- tem_1:=min_max[ply_plus_1,change_index];
- IF tem_1 < 32000 THEN
- BEGIN
- IF tem_1 > tem_2 THEN tem_2:=tem_1;
- min_max[ply_plus_1,change_index]:=32000
- END
- END;
- min_max[ply,branch[ply]]:=tem_2;
- IF tem_2 > -32000 THEN
- BEGIN
- IF ply_minus_1 > 0 THEN
- BEGIN
- change_index:=1;
- change_limit:=branch[ply_minus_1];
- skip_branch:=FALSE;
- WHILE ((change_index < change_limit)
- AND (NOT skip_branch)) DO
- BEGIN
- tem_1:=min_max[ply_minus_1,change_index];
- IF tem_1 < 32000 THEN
- IF tem_2 <= tem_1 THEN
- skip_branch:=TRUE
- ELSE
- change_index:=change_index+1
- ELSE
- change_index:=change_index+1
- END;
- IF skip_branch THEN
- BEGIN
- change_limit:=branch[ply];
- FOR change_index:=1 TO change_limit DO
- min_max[ply,change_index]:=-32000;
- branch[ply]:=1;
- ply:=ply_minus_1
- END
- END
- END
- END
- END
- END
- ELSE
- BEGIN
- change_index:=branch[ply];
- ply_minus_1:=ply-1;
- IF ODD(ply) THEN
- BEGIN
- next_column
- :=my_column[ply_minus_1]+column_change[change_index];
- next_row
- :=my_row[ply_minus_1]+row_change[change_index]
- END
- ELSE
- BEGIN
- next_column
- :=your_column[ply_minus_1]+column_change[change_index];
- next_row
- :=your_row[ply_minus_1]+row_change[change_index]
- END;
- IF on_board(next_column,next_row) THEN
- finished:=TRUE
- END
- END;
- IF ply > 0 THEN
- BEGIN
- ply_minus_1:=ply-1;
- WHILE (ply <= max_depth) DO
- BEGIN
- change_index:=branch[ply];
- valid_move_found:=FALSE;
- IF ODD(ply) THEN
- WHILE (NOT valid_move_found) DO
- BEGIN
- next_column
- :=my_column[ply_minus_1]+column_change[change_index];
- next_row
- :=my_row[ply_minus_1]+row_change[change_index];
- IF on_board(next_column,next_row) THEN
- BEGIN
- valid_move_found:=TRUE;
- my_column[ply]:=next_column;
- my_row[ply]:=next_row;
- your_column[ply]:=your_column[ply_minus_1];
- your_row[ply]:=your_row[ply_minus_1];
- partial_sum[ply]
- :=partial_sum[ply_minus_1]
- +board[ply_minus_1,next_column,next_row]
- END
- ELSE
- change_index:=change_index+1
- END
- ELSE
- WHILE (NOT valid_move_found) DO
- BEGIN
- next_column
- :=your_column[ply_minus_1]
- +column_change[change_index];
- next_row:=your_row[ply_minus_1]
- +row_change[change_index];
- IF on_board(next_column,next_row) THEN
- BEGIN
- valid_move_found:=TRUE;
- my_column[ply]:=my_column[ply_minus_1];
- my_row[ply]:=my_row[ply_minus_1];
- your_column[ply]:=next_column;
- your_row[ply]:=next_row;
- partial_sum[ply]
- :=partial_sum[ply_minus_1]
- -board[ply_minus_1,next_column,next_row]
- END
- ELSE
- change_index:=change_index+1
- END;
- branch[ply]:=change_index;
- FOR column:=0 TO 4 DO
- FOR row:=0 TO 4 DO
- board[ply,column,row]:=board[ply_minus_1,column,row];
- board[ply,next_column,next_row]:=0;
- ply:=ply+1;
- ply_minus_1:=ply_minus_1+1
- END;
- tem_2:=partial_sum[max_depth];
- min_max[max_depth,branch[max_depth]]:=tem_2;
- ply:=max_depth;
- ply_minus_1:=ply-1;
- IF ply_minus_1 > 0 THEN
- BEGIN
- IF ODD(ply) THEN
- BEGIN
- change_index:=1;
- change_limit:=branch[ply_minus_1];
- skip_branch:=FALSE;
- WHILE ((change_index < change_limit)
- AND (NOT skip_branch)) DO
- BEGIN
- tem_1:=min_max[ply_minus_1,change_index];
- IF tem_1 > -32000 THEN
- IF tem_2 >= tem_1 THEN
- skip_branch:=TRUE
- ELSE
- change_index:=change_index+1
- ELSE
- change_index:=change_index+1
- END;
- IF skip_branch THEN
- BEGIN
- change_limit:=branch[ply];
- FOR change_index:=1 TO change_limit DO
- min_max[ply,change_index]:=32000;
- branch[ply]:=1;
- ply:=ply_minus_1
- END
- END
- ELSE
- BEGIN
- change_index:=1;
- change_limit:=branch[ply_minus_1];
- skip_branch:=FALSE;
- WHILE ((change_index < change_limit)
- AND (NOT skip_branch)) DO
- BEGIN
- tem_1:=min_max[ply_minus_1,change_index];
- IF tem_1 < 32000 THEN
- IF tem_2 <= tem_1 THEN
- skip_branch:=TRUE
- ELSE
- change_index:=change_index+1
- ELSE
- change_index:=change_index+1
- END;
- IF skip_branch THEN
- BEGIN
- change_limit:=branch[ply];
- FOR change_index:=1 TO change_limit DO
- min_max[ply,change_index]:=-32000;
- branch[ply]:=1;
- ply:=ply_minus_1
- END
- END
- END
- END
- UNTIL (ply = 0);
- tem_1:=-32000;
- FOR change_index:=1 to 8 DO
- BEGIN
- tem_2:=min_max[1,change_index];
- IF tem_2 < 32000 THEN
- BEGIN
- IF tem_2 > tem_1 THEN
- BEGIN
- tem_1:=tem_2;
- final_change_index:=change_index
- END
- END
- END;
- next_column:=my_column[0]+column_change[final_change_index];
- next_row:=my_row[0]+row_change[final_change_index];
- my_column[0]:=next_column;
- my_row[0]:=next_row;
- tem_1:=board[0,next_column,next_row];
- my_score:=my_score+tem_1;
- IF tem_1 > 0 THEN
- tiles_visited:=tiles_visited+1;
- board[0,next_column,next_row]:=0;
- plys_left:=plys_left-1
- END;
- BEGIN
- ClrScr;
- WRITELN(OUTPUT,' Knight');
- WRITELN(OUTPUT,' ');
- WRITELN(OUTPUT,' ');
- WRITELN(OUTPUT,' ');
- display_rules;
- your_row[0]:=0;
- your_column[0]:=0;
- my_row[0]:=4;
- my_column[0]:=4;
- tiles_visited:=2;
- i_move_first:=NOT you_move_first;
- get_level_of_difficulty;
- max_plys:=level_of_difficulty;
- get_game_number;
- set_up_board;
- my_score:=0;
- your_score:=0;
- row_change[1]:=2; column_change[1]:=1;
- row_change[2]:=1; column_change[2]:=2;
- row_change[3]:=-1; column_change[3]:=2;
- row_change[4]:=-2; column_change[4]:=1;
- row_change[5]:=-2; column_change[5]:=-1;
- row_change[6]:=-1; column_change[6]:=-2;
- row_change[7]:=1; column_change[7]:=-2;
- row_change[8]:=2; column_change[8]:=-1;
- your_moves_left:=15;
- plys_left:=2*your_moves_left;
- IF i_move_first THEN
- WHILE ((tiles_visited < 25)
- AND (plys_left > 0)) DO
- BEGIN
- display_board;
- make_my_move;
- IF tiles_visited < 25 THEN
- BEGIN
- display_board;
- get_your_move
- END
- END
- ELSE
- WHILE ((tiles_visited < 25)
- AND (plys_left > 0)) DO
- BEGIN
- display_board;
- get_your_move;
- IF tiles_visited < 25 THEN
- BEGIN
- display_board;
- make_my_move
- END
- END;
- display_board;
- WRITELN(OUTPUT,' ');
- IF my_score > your_score THEN
- WRITELN(OUTPUT,' I win!')
- ELSE
- IF my_score < your_score THEN
- WRITELN(OUTPUT,' You win!')
- ELSE
- WRITELN(OUTPUT,' The game is a draw.')
- END.
-